package net.ainom.scarab.xmlrpc;

import java.util.Collection;
import java.util.Iterator;

import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.client.XmlRpcClient;
import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNLogEntry;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class ScarabIssueTracker extends AbstractScarabIssueTrackerIntegration {

    public ScarabIssueTracker() {
        super();
    }

    public void run() {
        FilterResponse fresp = new FilterResponse();

        SVNRepository repository = null;

        try {
            /*
             * Creates an instance of SVNRepository to work with the repository. All user's requests to the repository are relative
             * to the repository location used to create this SVNRepository. SVNURL is a wrapper for URL strings that refer to
             * repository locations.
             */
            repository = SVNRepositoryFactory.create(SVNURL.fromFile(repo));
        } catch (SVNException svne) {
            /*
             * Perhaps a malformed URL is the cause of this exception.
             */
            System.err.println("error while creating an SVNRepository for the location '" + repo.getAbsolutePath() + "': "
                    + svne.getMessage());
            System.exit(1);
        }

        /*
         * User's authentication information is provided via an ISVNAuthenticationManager instance. SVNWCUtil creates a default
         * usre's authentication manager given user's name and password.
         */
        ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password);

        /*
         * Sets the manager of the user's authentication information that will be used to authenticate the user to the server (if
         * needed) during operations handled by the SVNRepository.
         */
        repository.setAuthenticationManager(authManager);

        Collection logEntries = null;
        try {
            /*
             * Collects SVNLogEntry objects for all revisions in the range defined by its start and end points [startRevision,
             * endRevision]. For each revision commit information is represented by SVNLogEntry.
             * 
             * the 1st parameter (targetPaths - an array of path strings) is set when restricting the [startRevision, endRevision]
             * range to only those revisions when the paths in targetPaths were changed.
             * 
             * the 2nd parameter if non-null - is a user's Collection that will be filled up with found SVNLogEntry objects; it's
             * just another way to reach the scope.
             * 
             * startRevision, endRevision - to define a range of revisions you are interested in; by default in this program -
             * startRevision=0, endRevision= the latest (HEAD) revision of the repository.
             * 
             * the 5th parameter - a boolean flag changedPath - if true then for each revision a corresponding SVNLogEntry will
             * contain a map of all paths which were changed in that revision.
             * 
             * the 6th parameter - a boolean flag strictNode - if false and a changed path is a copy (branch) of an existing one in
             * the repository then the history for its origin will be traversed; it means the history of changes of the target URL
             * (and all that there's in that URL) will include the history of the origin path(s). Otherwise if strictNode is true
             * then the origin path history won't be included.
             * 
             * The return value is a Collection filled up with SVNLogEntry Objects.
             */
            logEntries = repository.log(new String[] { "" }, null, rev, rev, true, true);

        } catch (SVNException svne) {
            System.err.println("error while collecting log information for '" + repo.getAbsolutePath() + "': " + svne.getMessage());
            System.exit(1);
        }
        for (Iterator entries = logEntries.iterator(); entries.hasNext();) {
            // We're iterating through log messages here.
            SVNLogEntry logEntry = (SVNLogEntry) entries.next();
            Iterator i = this.filter.iterator();
            while (i.hasNext()) {
                Filter f = (Filter) i.next();
                try {
                    fresp = f.filter(fresp, logEntry);
                    if (fresp.getResponse() == 0)
                        break;
                    if (fresp.getResponse() < 0) {
                        System.err.println("Filter " + f + " returned " + fresp.getResponse() + " " + fresp.getErrorData());
                        return;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    return; // Doing nothing else
                }

            }
        }

        // @TODO Work a bit on the call to the XMLRPC here....
        String author = fresp.getAuthor();
        if (userIdMapping.containsKey(author))
            author = (String) userIdMapping.get(author);

        XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
        config.setServerURL(issueTrackingActionUrl);

        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);
        Iterator iList = fresp.getIssues().iterator();
        while (iList.hasNext()) {
            String _iss = (String) iList.next();
            try {
                Object[] params = new Object[] { _iss, author, fresp.toString(), new Integer(1) };
                Object result = client.execute("simple.addComment", params);
                System.out.println(result); // Dunno if we want to do this
            } catch (XmlRpcException e) {
                // @TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
